package com.yangyang.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class MyThread<T> extends Thread {
    //private List<String[]> list;//操作的数据
    private List<T> list;//操作的数据
    private CountDownLatch begin;//计数器
    private CountDownLatch end;//计数器
    private Connection connection;
    private  String  sql;

    //创建个构造函数初始化 list,和其他用到的参数
/*    public MyThread(List<String[]> list, CountDownLatch begin, CountDownLatch end, Connection connection, String sql) {
        this.list = list;
        this.begin = begin;
        this.end = end;
        this.connection = connection;
        this.sql = sql;
    }*/
    public MyThread(List<T> list, CountDownLatch begin, CountDownLatch end, Connection connection, String sql) {
        this.list = list;
        this.begin = begin;
        this.end = end;
        this.connection = connection;
        this.sql = sql;
    }

    @Override
    public void run() {
        System.out.println(connection+"------------------------");
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
                for (int i = 0; i < list.size(); i++) {
                    //这里还要说一下，，由于在实质项目中，当处理的数据存在等待超时和出错会使线程一直处于等待状态
                    //这里只是处理简单的，
                    //分批 批量插入
                    Object o= list.get(i);
                    Class clazz = o.getClass();//获取class
                    Field[] fields = clazz.getDeclaredFields();//得到所有属性
                    for (int j=0;j<fields.length;j++){
                        fields[j].setAccessible(true);
                        String value= fields[j].get(o)+"";//获取属性值
                        preparedStatement.setObject(j+1,value);
                    }
                    preparedStatement.addBatch();//将所有数据转成一条sql
                }
            preparedStatement.executeBatch();
            preparedStatement.close();
            //执行完让线程直接进入等待
            begin.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //这里要主要了，当一个线程执行完 了计数要减一不然这个线程会被一直挂起
            // ，end.countDown()，这个方法就是直接把计数器减一的
            end.countDown();
        }
    }

}
